package com.squid.base.utils;

import com.squid.base.common.error.ExceptionFactory;
import jakarta.annotation.Resource;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validator;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author jh
 * @date 2023/2/27 17:15
 */
@Component
public class ValidatorUtils {
    /**
     * 手机
     */
    private static final Pattern PHONE_PATTERN = Pattern.compile("1\\d{10}");
    /**
     * 中国公民身份证号码最小长度。
     */
    private static final int CHINA_ID_MIN_LENGTH = 15;
    /**
     * 中国公民身份证号码最大长度。
     */
    private static final int CHINA_ID_MAX_LENGTH = 18;
    private static Validator validator;

    /**
     * 验证手机号
     *
     * @param phone 手机号
     * @return true or false
     */
    public static Boolean isPhone(String phone) {
        if (StringUtils.isEmpty(phone)) {
            return false;
        }
        Matcher matcher = PHONE_PATTERN.matcher(phone);
        return matcher.matches();
    }

    /**
     * list校验
     *
     * @param list 校验list
     * @param <T>  泛型
     */
    public static <T> void valid(List<T> list) {
        //对参数进行校验
        for (int i = 0; i < list.size(); i++) {
            T dto = list.get(i);
            Set<ConstraintViolation<T>> validate = validator.validate(dto);
            if (!validate.isEmpty()) {
                throw ExceptionFactory.instanceBusinessException("第" + (i + 1) + "行" + validate.iterator().next().getMessage());
            }
        }
    }

    /**
     * 返回一个错误信息
     *
     * @param dto 校验对象
     * @param <T> 泛型
     */
    public static <T> void valid(T dto) {
        Set<ConstraintViolation<T>> validate = validator.validate(dto);
        if (!validate.isEmpty()) {
            throw ExceptionFactory.instanceBusinessException(validate.iterator().next().getMessage());
        }
    }

    /**
     * 返回所有错误信息
     *
     * @param dto 校验对象
     * @param <T> 泛型
     */
    public static <T> void validates(T dto) {
        Set<ConstraintViolation<T>> validate = validator.validate(dto);
        if (!validate.isEmpty()) {
            String errorMessage = validate.stream().map(ConstraintViolation::getMessage).collect(Collectors.joining(";"));
            throw ExceptionFactory.instanceBusinessException(errorMessage);
        }
    }

    /**
     * 身份证号长度校验
     *
     * @return {@link String }
     * @author zhangchaodong
     * @date 2023/04/20
     */
    public static Boolean idCardLengthUtil(String idCard) {
        if (StringUtils.isEmpty(idCard)) {
            return true;
        }
        if (idCard.length() != CHINA_ID_MIN_LENGTH && idCard.length() != CHINA_ID_MAX_LENGTH) {
            return false;
        }
        return true;
    }

    /**
     * 获取字符串的长度，如果有中文，则每个中文字符计为2位,中文逗号也为2
     *
     * @param value 指定的字符串
     * @return 字符串的长度
     */

    public static int length(String value) {

        int valueLength = 0;
        String chinese = "[\u0391-\uFFE5]";
        //获取字段值的长度，如果含中文字符，则每个中文字符长度为2，否则为1
        for (int i = 0; i < value.length(); i++) {
            //获取一个字符
            String temp = value.substring(i, i + 1);
            //判断是否为中文字符
            if (temp.matches(chinese)) {
                //中文字符长度为2
                valueLength += 2;
            } else {
                //其他字符长度为1
                valueLength += 1;
            }
        }
        return valueLength;

    }

    /**
     * 是否包含特定字符
     *
     * @param str str
     * @return boolean 包含返回true
     */
    public static boolean isSpecialChar(String str) {
        String regEx = "[ ∏¥§℅€℃£℉№℡‰$¢∮※？?<>'&\\[\\]]|\n|\r|\t";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        return m.find();
    }

    /**
     * 导入入参长度和特殊字符校验
     *
     * @param str    入参字段
     * @param length 限制长度
     * @return boolean true 表示没有问题
     */
    public static boolean importCheck(String str, int length) {
        int strLength = ValidatorUtils.length(str);
        if (strLength > length) {
            return false;
        }
        if (ValidatorUtils.isSpecialChar(str)) {
            return false;
        }
        return true;

    }

    /**
     * 导入入参长度校验
     *
     * @param str    入参字段
     * @param length 限制长度
     * @return boolean true 表示没有问题
     */
    public static boolean lengthCheck(String str, int length) {
        int strLength = ValidatorUtils.length(str);
        if (strLength > length) {
            return false;
        }
        return true;
    }

    /**
     * 只取中文，匹配
     *
     * @param str str
     * @return {@link String }
     * @author jh
     * date 2023/06/16
     */
    public static String chineseMatch(String str) {

        //双字符，如果匹配不到，在用这个
        String twoChar = "[^\\x00-\\xff]+";
        //中文字符
        String chinesePattern = "[\\u4e00-\\u9fa5]+";
        Pattern pattern = Pattern.compile(chinesePattern);
        Matcher matcher = pattern.matcher(str);
        if (matcher.find()) {
            return matcher.group();
        }
        return "";
    }

    /**
     * 是字母或者数字
     *
     * @param str str
     * @return boolean 包含返回true
     */
    public static boolean isNumbersOrLetters(String str) {
        String regEx = "^[A-Za-z0-9]+$";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        return m.find();
    }

    @Resource
    public void setValidator(Validator validator) {
        ValidatorUtils.validator = validator;
    }
}
